import {
  WebSocketGateway,
  WebSocketServer,
  SubscribeMessage,
  OnGatewayConnection,
  OnGatewayDisconnect,
  MessageBody,
  ConnectedSocket,
} from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';
import { WsMessage, WsResponse } from '../common/interfaces/base.interface';
import { Logger } from '@nestjs/common';

@WebSocketGateway(3001, {
  cors: {
    origin: '*', // 在生产环境中应该限制来源
  },
})
export class AppGateway implements OnGatewayConnection, OnGatewayDisconnect {
  private readonly logger = new Logger(AppGateway.name);

  @WebSocketServer()
  server: Server;

  private connectedClients: Map<string, Socket> = new Map();

  // 连接处理
  handleConnection(client: Socket) {
    this.logger.log(`Client connected: ${client.id}`);
    this.connectedClients.set(client.id, client);
  }

  // 断开连接处理
  handleDisconnect(client: Socket) {
    this.logger.log(`Client disconnected: ${client.id}`);
    this.connectedClients.delete(client.id);
  }

  // 示例：处理消息
  @SubscribeMessage('message')
  async handleMessage(
    @ConnectedSocket() client: Socket,
    @MessageBody() message: WsMessage
  ): Promise<WsResponse> {
    this.logger.log(
      `Received message from ${client.id}: ${JSON.stringify(message)}`
    );

    return {
      type: 'message_response',
      timestamp: Date.now(),
      requestId: message.requestId,
      status: 'success',
      message: 'Message received',
      data: message.payload,
    };
  }

  // 示例：加入房间
  @SubscribeMessage('joinRoom')
  async handleJoinRoom(
    @ConnectedSocket() client: Socket,
    @MessageBody() message: WsMessage
  ): Promise<WsResponse> {
    if (message.room) {
      await client.join(message.room);
      this.logger.log(`Client ${client.id} joined room: ${message.room}`);

      return {
        type: 'room_join_response',
        timestamp: Date.now(),
        requestId: message.requestId,
        status: 'success',
        message: `Joined room: ${message.room}`,
      };
    }

    return {
      type: 'room_join_response',
      timestamp: Date.now(),
      requestId: message.requestId,
      status: 'error',
      message: 'Room name is required',
    };
  }

  // 示例：向房间广播消息
  @SubscribeMessage('roomMessage')
  async handleRoomMessage(
    @ConnectedSocket() client: Socket,
    @MessageBody() message: WsMessage
  ): Promise<WsResponse> {
    if (message.room && message.payload) {
      this.server.to(message.room).emit('roomMessage', {
        type: 'room_message',
        timestamp: Date.now(),
        payload: message.payload,
        sender: client.id,
      });

      return {
        type: 'room_message_response',
        timestamp: Date.now(),
        requestId: message.requestId,
        status: 'success',
        message: 'Message sent to room',
      };
    }

    return {
      type: 'room_message_response',
      timestamp: Date.now(),
      requestId: message.requestId,
      status: 'error',
      message: 'Room name and message are required',
    };
  }
}
